#include "Moto.h"
#include "GameManager.h"
#include "CEMoveBySpeed.h"
#include "Road.h"

Moto::Moto() {}
Moto::~Moto() {}

bool Moto::init() {return true;}

void Moto::update(float delta){
	Vehicle::update(delta);

	if(delta > TIME_NOT_UPDATE)
		return;

	/*if(isBesideSafe()){
		noTurn();
	}*/

	checkTurnBeside();
	if(road->getBusLaneMode() != BLM_BUS_MOTOR){
		checkTurnLane();
	}
	checkTurnDone();
}

void Moto::turnRight(float horizontalTarget){
	horizontalDirection = HD_RIGHT;
	v.y = -calculateVTurn();
	this->horizontalTarget = horizontalTarget;
	numTurn++;
}
void Moto::turnLeft(float horizontalTarget){
	horizontalDirection = HD_LEFT;
	v.y = calculateVTurn();
	this->horizontalTarget = horizontalTarget;
	numTurn++;
}

CCRect Moto::getLeftSafeRect(){
	return leftSafeRectNextLane;
}
CCRect Moto::getRightSafeRect(){
	return rightSafeRectNextLane;
}

void Moto::checkTurnLane(){
	if(isSafe == false && horizontalDirection == HD_NONE){

		// check turn right
		bool isRightCanTurn = true;

		if(rightSafeRectNextLane.origin.y > 0){    // in road when turn right

			CCObject* it;
			CCARRAY_FOREACH(road->getVehicles(), it){
				Vehicle* vehicle = (Vehicle*)it;
				if(isInInteractableRange(vehicle)){
					if(rightSafeRectNextLane.intersectsRect(vehicle->boundingBox())
						|| (
						vehicle->isSafe == false
						&& (
						rightSafeRectNextLane.intersectsRect(vehicle->getLeftSafeRectNextLane()) 
						|| rightSafeRectNextLane.intersectsRect(vehicle->getLeftSafeRectBeside())
						)
						)
						){
							isRightCanTurn = false;
							break;
					}
				}
			}

			if(isRightCanTurn){
				turnRight(getPositionY() - road->getLaneWidth());
			}
		}
		else isRightCanTurn = false;

		if(isRightCanTurn == false){
			// check turn left
			if(leftSafeRectNextLane.getMaxY() < road->getRoadWidth() && road->checkVehicleCanTurnBusLaneMode(leftSafeRectNextLane, getTag())){    // in road when turn left

				CCObject* it;
				bool isLeftCanTurn = true;
				CCARRAY_FOREACH(road->getVehicles(), it){
					Vehicle* vehicle = (Vehicle*)it;
					if(isInInteractableRange(vehicle)){
						if(leftSafeRectNextLane.intersectsRect(vehicle->boundingBox())
							|| (
							vehicle->isSafe == false
							&& (
							leftSafeRectNextLane.intersectsRect(vehicle->getRightSafeRectNextLane()) 
							|| leftSafeRectNextLane.intersectsRect(vehicle->getRightSafeRectBeside()))
							)
							){
								isLeftCanTurn = false;
								break;
						}
					}
				}

				if(isLeftCanTurn){
					turnLeft(getPositionY() + road->getLaneWidth());
				}
			}
		}
	}
}

void Moto::checkTurnBeside(){
	if(isSafe == false && horizontalDirection == HD_NONE && 
		(leftSafeRectBeside.equals(CCRectZero) == false || rightSafeRectBeside.equals(CCRectZero) == false)){

		// check turn right
		bool isRightCanTurn = true;

		if(rightSafeRectBeside.origin.y > 0){    // in road when turn right

			CCObject* it;
			CCARRAY_FOREACH(road->getVehicles(), it){
				Vehicle* vehicle = (Vehicle*)it;
				if(isInInteractableRange(vehicle)){
					if(rightSafeRectBeside.intersectsRect(vehicle->boundingBox())
						|| (
						vehicle->isSafe == false
						&& (
						rightSafeRectBeside.intersectsRect(vehicle->getLeftSafeRectNextLane()) 
						|| rightSafeRectBeside.intersectsRect(vehicle->getLeftSafeRectBeside())
						)
						)
						){
							isRightCanTurn = false;
							break;
					}
				}
			}

			// check if bus lane mode is motor and right safe rect beside out bus lane
			if(road->getBusLaneMode() == BLM_BUS_MOTOR && road->rectEntireInLane(rightSafeRectBeside) != 1){
				isRightCanTurn = false;
			}

			if(isRightCanTurn){
				turnRight(rightSafeRectBeside.getMidY());
			}
		}
		else isRightCanTurn = false;

		if(isRightCanTurn == false){
			// check turn left
			if(leftSafeRectBeside.getMaxY() < road->getRoadWidth() && road->checkVehicleCanTurnBusLaneMode(leftSafeRectBeside, getTag())){    // in road when turn left
				CCObject* it;
				bool isLeftCanTurn = true;
				CCARRAY_FOREACH(road->getVehicles(), it){
					Vehicle* vehicle = (Vehicle*)it;
					if(isInInteractableRange(vehicle)){
						if(leftSafeRectBeside.intersectsRect(vehicle->getSafeRect())
							|| (
							vehicle->isSafe == false
							&& (
							leftSafeRectBeside.intersectsRect(vehicle->getRightSafeRectNextLane()) 
							|| leftSafeRectBeside.intersectsRect(vehicle->getRightSafeRectBeside())
							)
							)
							){
								isLeftCanTurn = false;
								break;
						}
					}
				}

				if(isLeftCanTurn){
					turnLeft(leftSafeRectBeside.getMidY());
				}
				/*else{
					noTurn();
				}*/
			}
		}
	}
}

void Moto::noTurn(){
	Vehicle::noTurn();

	updateLaneInfo();
}

void Moto::updateLaneInfo(){
	int whichLane = road->getWhichLane(this);
	switch (whichLane)
	{
	case 1:
		if(isInLane1 == false){
			GameManager::getInstance()->numMotoLane1++;
			isInLane1 = true;
		}
		break;

	case 2:
		if(isInLane2 == false){
			GameManager::getInstance()->numMotoLane2++;
			isInLane2 = true;
		}
		break;

	case 3:
		if(isInLane3 == false){
			GameManager::getInstance()->numMotoLane3++;
			isInLane3 = true;
		}
		break;
	}
}